<template>
  <div class="json-formatter-tool">
    <div class="tool-header">
      <h1>JSON格式化工具</h1>
      <p>格式化、验证和美化JSON数据</p>
    </div>

    <div class="tool-container">
      <el-row :gutter="20">
        <!-- 输入区域 -->
        <el-col :span="12">
          <div class="input-section">
            <div class="section-header">
              <h3>JSON输入</h3>
              <div class="actions">
                <el-button @click="clearInput" size="small">清空</el-button>
                <el-button @click="pasteFromClipboard" size="small" type="primary">粘贴</el-button>
                <el-button @click="loadExample" size="small" type="success">示例</el-button>
              </div>
            </div>
            
            <el-input
              v-model="inputJson"
              type="textarea"
              :rows="12"
              placeholder="请输入JSON数据..."
              @input="handleInput"
              :class="{ 'error-input': hasError }"
            />
            
            <div class="input-info" v-if="inputJson">
              <el-tag :type="hasError ? 'danger' : 'success'" size="small">
                {{ hasError ? 'JSON格式错误' : 'JSON格式正确' }}
              </el-tag>
              <el-tag type="info" size="small" v-if="!hasError">
                字符数: {{ inputJson.length }}
              </el-tag>
            </div>
            
            <div class="error-message" v-if="errorMessage">
              <el-alert
                :title="errorMessage"
                type="error"
                :closable="false"
                show-icon
              />
            </div>
          </div>
        </el-col>

        <!-- 输出区域 -->
        <el-col :span="12">
          <div class="output-section">
            <div class="section-header">
              <h3>格式化结果</h3>
              <div class="actions">
                <el-button @click="copyResult" size="small" :disabled="!formattedJson">复制</el-button>
                <el-button @click="downloadJson" size="small" :disabled="!formattedJson">下载</el-button>
                <el-button @click="clearOutput" size="small">清空</el-button>
              </div>
            </div>
            
            <el-input
              v-model="formattedJson"
              type="textarea"
              :rows="12"
              placeholder="格式化后的JSON将显示在这里..."
              readonly
            />
            
            <div class="output-actions">
              <el-button-group>
                <el-button @click="formatJson" :disabled="!inputJson || hasError" size="small">
                  <el-icon><Edit /></el-icon>
                  格式化
                </el-button>
                <el-button @click="minifyJson" :disabled="!inputJson || hasError" size="small">
                  <el-icon><Operation /></el-icon>
                  压缩
                </el-button>
                <el-button @click="validateJson" :disabled="!inputJson" size="small">
                  <el-icon><Check /></el-icon>
                  验证
                </el-button>
              </el-button-group>
            </div>
          </div>
        </el-col>
      </el-row>

      <!-- JSON信息面板 -->
      <div class="json-info" v-if="jsonInfo">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>JSON信息</span>
            </div>
          </template>
          
          <div class="info-grid">
            <div class="info-item">
              <span class="label">类型:</span>
              <el-tag :type="jsonInfo.type === 'object' ? 'primary' : 'success'">
                {{ jsonInfo.type }}
              </el-tag>
            </div>
            <div class="info-item">
              <span class="label">键数量:</span>
              <span class="value">{{ jsonInfo.keyCount }}</span>
            </div>
            <div class="info-item">
              <span class="label">嵌套深度:</span>
              <span class="value">{{ jsonInfo.depth }}</span>
            </div>
            <div class="info-item">
              <span class="label">大小:</span>
              <span class="value">{{ formatBytes(jsonInfo.size) }}</span>
            </div>
          </div>
        </el-card>
      </div>

      <!-- 使用说明 -->
      <div class="tool-info">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>使用说明</span>
            </div>
          </template>
          
          <div class="info-content">
            <h4>功能特点：</h4>
            <ul>
              <li><strong>格式化：</strong>美化JSON格式，提高可读性</li>
              <li><strong>压缩：</strong>去除多余空格，减小文件大小</li>
              <li><strong>验证：</strong>检查JSON语法是否正确</li>
              <li><strong>分析：</strong>显示JSON结构和统计信息</li>
            </ul>
            
            <h4>使用场景：</h4>
            <ul>
              <li>API接口调试</li>
              <li>配置文件格式化</li>
              <li>数据传输优化</li>
              <li>代码审查</li>
            </ul>
          </div>
        </el-card>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { Edit, Operation, Check } from '@element-plus/icons-vue'

const inputJson = ref('')
const formattedJson = ref('')
const errorMessage = ref('')
const jsonInfo = ref(null)

const hasError = computed(() => !!errorMessage.value)

const handleInput = () => {
  if (inputJson.value.trim()) {
    validateJson()
  } else {
    clearOutput()
  }
}

const validateJson = () => {
  try {
    const parsed = JSON.parse(inputJson.value)
    errorMessage.value = ''
    analyzeJson(parsed)
    return true
  } catch (error) {
    errorMessage.value = error.message
    jsonInfo.value = null
    return false
  }
}

const formatJson = () => {
  if (!validateJson()) return
  
  try {
    const parsed = JSON.parse(inputJson.value)
    formattedJson.value = JSON.stringify(parsed, null, 2)
    ElMessage.success('JSON格式化完成')
  } catch (error) {
    ElMessage.error('格式化失败：' + error.message)
  }
}

const minifyJson = () => {
  if (!validateJson()) return
  
  try {
    const parsed = JSON.parse(inputJson.value)
    formattedJson.value = JSON.stringify(parsed)
    ElMessage.success('JSON压缩完成')
  } catch (error) {
    ElMessage.error('压缩失败：' + error.message)
  }
}

const analyzeJson = (obj) => {
  const info = {
    type: Array.isArray(obj) ? 'array' : typeof obj,
    keyCount: 0,
    depth: 0,
    size: JSON.stringify(obj).length
  }
  
  if (typeof obj === 'object' && obj !== null) {
    info.keyCount = Object.keys(obj).length
    info.depth = getDepth(obj)
  }
  
  jsonInfo.value = info
}

const getDepth = (obj, currentDepth = 0) => {
  if (typeof obj !== 'object' || obj === null) {
    return currentDepth
  }
  
  let maxDepth = currentDepth
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      const depth = getDepth(obj[key], currentDepth + 1)
      maxDepth = Math.max(maxDepth, depth)
    }
  }
  
  return maxDepth
}

const formatBytes = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const clearInput = () => {
  inputJson.value = ''
  clearOutput()
  ElMessage.info('已清空输入内容')
}

const clearOutput = () => {
  formattedJson.value = ''
  errorMessage.value = ''
  jsonInfo.value = null
}

const copyResult = async () => {
  if (!formattedJson.value) {
    ElMessage.warning('没有可复制的内容')
    return
  }
  
  try {
    await navigator.clipboard.writeText(formattedJson.value)
    ElMessage.success('已复制到剪贴板')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

const downloadJson = () => {
  if (!formattedJson.value) {
    ElMessage.warning('没有可下载的内容')
    return
  }
  
  const blob = new Blob([formattedJson.value], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = 'formatted.json'
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
  ElMessage.success('文件下载完成')
}

const pasteFromClipboard = async () => {
  try {
    const text = await navigator.clipboard.readText()
    inputJson.value = text
    validateJson()
    ElMessage.success('已粘贴内容')
  } catch (error) {
    ElMessage.error('无法访问剪贴板，请手动粘贴')
  }
}

const loadExample = () => {
  const example = {
    "name": "在线工具集合",
    "version": "1.0.0",
    "description": "提供各种实用的在线工具",
    "features": [
      "文本处理",
      "图片处理",
      "编码解码"
    ],
    "author": {
      "name": "开发者",
      "email": "dev@example.com"
    },
    "settings": {
      "theme": "light",
      "language": "zh-CN",
      "autoSave": true
    }
  }
  
  inputJson.value = JSON.stringify(example, null, 2)
  validateJson()
  ElMessage.success('已加载示例数据')
}
</script>

<style scoped>
.json-formatter-tool {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.tool-header {
  text-align: center;
  margin-bottom: 40px;
}

.tool-header h1 {
  font-size: 2.5rem;
  color: #333;
  margin-bottom: 10px;
}

.tool-header p {
  color: #666;
  font-size: 1.1rem;
}

.tool-container {
  margin-bottom: 40px;
}

.input-section,
.output-section {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid #f0f0f0;
  height: 100%;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.section-header h3 {
  color: #333;
  margin: 0;
  font-size: 1.3rem;
}

.actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.error-input :deep(.el-textarea__inner) {
  border-color: #f56c6c;
}

.input-info {
  margin-top: 15px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.error-message {
  margin-top: 15px;
}

.output-actions {
  margin-top: 15px;
  display: flex;
  justify-content: center;
}

.json-info {
  margin: 30px 0;
}

.card-header {
  font-weight: bold;
  color: #333;
}

.info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
}

.info-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  background: #f8f9fa;
  border-radius: 6px;
}

.info-item .label {
  font-weight: 500;
  color: #666;
}

.info-item .value {
  font-weight: bold;
  color: #333;
}

.tool-info {
  margin-top: 40px;
}

.info-content h4 {
  color: #333;
  margin: 20px 0 10px 0;
  font-size: 1.1rem;
}

.info-content ul {
  color: #666;
  padding-left: 20px;
  margin-bottom: 15px;
}

.info-content li {
  margin-bottom: 5px;
}

@media (max-width: 768px) {
  .tool-header h1 {
    font-size: 2rem;
  }
  
  .section-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
  
  .actions {
    width: 100%;
    justify-content: flex-start;
  }
  
  .info-grid {
    grid-template-columns: 1fr;
  }
}
</style>
